package com.ourteam.sourcecode.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

public class SourceLineCounter {

	public static void main(String[] args) {
		File f = new File("/Users/qilin/SpmsSCMBase/voice");

		SourceLineBean[] lineBeans = SourceLineCounter.scanDir(f, new String[] { "java" }, true);

		for (int i = 0; i < lineBeans.length; i++) {
			System.out.println(lineBeans[i]);
		}

		// System.out.println("commentlines:" + commentlines);
		// System.out.println("blanklines:" + blanklines);
		// System.out.println("codelines:" + codelines);
	}

	public static SourceLineBean[] scanDir(File dir, String[] extensions, boolean recursive) {

		if (dir.isFile()) {
			return new SourceLineBean[0];
		}

		Iterator<File> files = FileUtils.iterateFiles(dir, extensions, recursive);

		List<SourceLineBean> lineBeans = new ArrayList<>();

		SourceLineBean dirLineBean = new SourceLineBean();

		dirLineBean.setFilePath(dir.getPath());

		lineBeans.add(dirLineBean);

		long commentlines = 0;
		long blanklines = 0;
		long codelines = 0;

		while (files.hasNext()) {
			File file = files.next();
			SourceLineBean lineBean = parse(file);

			codelines += lineBean.getCodeLines();
			commentlines += lineBean.getCommentLines();
			blanklines += lineBean.getBlankLines();

			lineBeans.add(lineBean);
		}

		dirLineBean.setBlankLines(blanklines);
		dirLineBean.setCodeLines(codelines);
		dirLineBean.setCommentLines(commentlines);

		return lineBeans.toArray(new SourceLineBean[lineBeans.size()]);

	}

	public static SourceLineBean parse(InputStream f) {

		BufferedReader br = null;
		boolean comment = false;
		long commentlines = 0;
		long blanklines = 0;
		long codelines = 0;
		SourceLineBean lineBean = new SourceLineBean();
		try {
			br = new BufferedReader(new InputStreamReader(f));
			String s = null;
			try {
				while ((s = br.readLine()) != null) {
					s = s.trim();
					if (s.startsWith("/*") && (s.endsWith("*/"))) {
						commentlines++;
					} else if (s.startsWith("//")) {
						commentlines++;
					} else if (s.startsWith("/*") && !s.endsWith("*/")) {
						commentlines++;
						comment = true;
					} else if (true == comment) {
						commentlines++;
						if (s.endsWith("*/")) {
							comment = false;
						}
					} else if (s.matches("^[\\s&&[^\\n]]*$")) {
						blanklines++;
					} else {
						codelines++;
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			lineBean.setBlankLines(blanklines);
			lineBean.setCodeLines(codelines);
			lineBean.setCommentLines(commentlines);
			return lineBean;
		} catch (Exception e) {
			e.printStackTrace();
			return lineBean;
		} finally {
			if (br != null) {
				try {
					br.close();
					br = null;
				} catch (IOException e) {
					e.printStackTrace();
				}

			}

		}

	}

	public static SourceLineBean parse(File f) {
		
		SourceLineBean lineBean = new SourceLineBean();
		lineBean.setFilePath(f.getPath());
		InputStream inputStream = null;
		try {
			inputStream = FileUtils.openInputStream(f);
			SourceLineBean sourceLineBean = parse(inputStream);
			return sourceLineBean;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if (inputStream != null) {
				IOUtils.closeQuietly(inputStream);
			}
		}

	}
}
